{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# SVM支持向量机 "
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- 这里我们叙述的是最简单的线性支持向量机\n",
    "![image.png](https://img-blog.csdnimg.cn/20200916085324603.png)"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 目的：在感知机算法的基础上找到一条与两类样本间隔最大的分隔线。\n",
    "### SVM的基本思想：\n",
    "从上图我们可以得到距离之和为 $\\gamma=2/||W||$，||W||表示W的二范数，要使$\\gamma$最大，于是问题转化为求最小的||W||。\n",
    "- 于是我们可以得到一个含线性约束条件的二次优化问题：\n",
    "![image-4.png](https://img-blog.csdn.net/20170923172648006?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvYzQwNjQ5NTc2Mg==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)\n",
    "- 求解步骤：\n",
    "1. 采用拉格朗日乘子法：\n",
    "![image-5.png](https://img-my.csdn.net/uploads/201210/25/1351142114_6643.jpg)"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "2. 函数$\L(w,b,α)$分别对w,b求偏导并令为0，可以得到：\n",
    "![image.png](https://img-blog.csdn.net/20131107202220500)\n",
    "3. 将其代回$\L(w,b,α)$中，从而得到求解问题变为：\n",
    "![image-3.png](https://img-my.csdn.net/uploads/201210/25/1351142449_6864.jpg)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "至此我们可以看出，只要求出了$α_i$，就可以得到最优的W，进而通过KKT条件求出最佳的b，此时我们就完成了最优向量的求解。\n",
    "以上就是SVM的基本思想，我们可以通过Python中的sklearn调用线性SVM来实现一些简单的二分类\n",
    "\n",
    "附：KKT条件为：\n",
    "![image.png](https://img-blog.csdnimg.cn/20190127114104532.jpg)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "功能：使用sklearn实现线性SVM进行二分类，并画出支持向量及分隔直线"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "测试分数为: 1.00\n",
      "w:  [-0.03759018  0.35662109]\n",
      "a:  0.10540650630572106\n",
      "支持向量:  [[ 8.33791276 -2.92715505]\n",
      " [ 7.31309047  2.57359549]\n",
      " [ 8.40723476  2.68834432]]\n",
      "每个类的支持向量的个数:  [1 2]\n"
     ]
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "import numpy as np\n",
    "from sklearn.datasets import make_blobs\n",
    "import matplotlib.pyplot as plt\n",
    "from sklearn.svm import SVC\n",
    "from sklearn.model_selection import train_test_split\n",
    "\n",
    "\n",
    "def y_line(a, x, input_vector):\n",
    "    '''\n",
    "    线性支持向量机linear——SVM\n",
    "    :param a:支持向量斜率\n",
    "    :param x:横坐标\n",
    "    :param input_vector:输入的支持向量\n",
    "    :return: 支持向量所在直线\n",
    "    '''\n",
    "    b = input_vector\n",
    "    y = a * x + (b[1] - a * b[0])\n",
    "    return y\n",
    "\n",
    "\n",
    "X, y = make_blobs(n_samples=50, n_features=2, centers=2, random_state=150, cluster_std=1.0)\n",
    "X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=150)\n",
    "clf = SVC(kernel='linear')  # 线性SVM\n",
    "clf.fit(X_train, y_train)  # 训练\n",
    "print('测试分数为:', \"%.2f\" % clf.score(X_test, y_test))\n",
    "\n",
    "w = clf.coef_[0]  # 分割超平面的参数权值\n",
    "a = -w[0] / w[1]  # 超平面直线的斜率   边界线方程为w1y+w0x+b=0 --->  y= -w0/w1*x-b/w1\n",
    "xx = np.linspace(-5, 15)  # 从-5到15上取x\n",
    "yy = a * xx - (clf.intercept_[0]) / w[1]   # clf.intercept_[] 用来获得截距(这里共有两个值，分别为到x和到y的)\n",
    "yy_down = y_line(a, xx, clf.support_vectors_[0])\n",
    "yy_up = y_line(a, xx, clf.support_vectors_[-1])\n",
    "\n",
    "print(\"w: \", w)\n",
    "print(\"a: \", a)\n",
    "print(\"支持向量: \", clf.support_vectors_)\n",
    "print(\"每个类的支持向量的个数: \", clf.n_support_)\n",
    "\n",
    "# 画图\n",
    "plt.plot(xx, yy, 'k-')\n",
    "plt.plot(xx, yy_down, 'k--')  # 分界线\n",
    "plt.plot(xx, yy_up, 'k--')\n",
    "plt.scatter(clf.support_vectors_[:, 0],  # 正类的支持向量\n",
    "            clf.support_vectors_[:, 1],  # 反类的支持向量\n",
    "            s=60,  # 点的半径大小\n",
    "            marker='x',  # 支持变量的形状打上x，便于辨别\n",
    "            facecolors='red')  # face colors，支持向量的样本点的颜色\n",
    "plt.scatter(X[:, 0],  # 样本的 x 轴数据\n",
    "            X[:, 1],  # 样本集的 y 轴数据\n",
    "            c=y,  # 分类结果  c=y表示按照y的值来区分，c='y'表示点的颜色为黄色\n",
    "            cmap=plt.cm.Paired)\n",
    "# cmap确定颜色，paired表示两个两个相近色彩输出，比如浅蓝、深蓝；浅红、深红；浅绿，深绿这种\n",
    "plt.axis('tight')\n",
    "plt.show()"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.9"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
